package service

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/sha1"
	"encoding/base64"
	"encoding/binary"
	"fmt"
	"sort"
	"strings"

	"github.com/gin-gonic/gin"
)

const (
	token  = "zhilianxingtu20280109"                       // 你的Token
	msgKey = "WagvmsXsPAaPTJUAM19ygQzsIYEwGvTDniOQuTGVpt4" // 消息密钥(用于消息加解密)
	appID  = "wx3cc05e383e94e416"                          // 你的AppID
)

func verifyWeChat(c *gin.Context) {
	signature := c.Query("signature")
	timestamp := c.Query("timestamp")
	nonce := c.Query("nonce")
	echostr := c.Query("echostr")

	// 验证签名
	if CheckSignature(signature, timestamp, nonce) {
		c.String(200, echostr)
	} else {
		c.String(403, "验证失败")
	}
}

// 处理微信服务器的POST消息
func NandleWeChatMessage(c *gin.Context) {

	// 这里处理微信小店的消息推送
	// 需要实现消息的解密和业务逻辑处理
	// 示例中只返回success表示接收成功
	// 配置参数
	type Tddd struct {
		EncryptMsg string `json:"Encrypt" form:"Encrypt"`
	}
	var ccc Tddd
	if err := c.Bind(&ccc); err != nil {
		fmt.Println(err)
		return
	}

	encodingAESKey := msgKey + "="
	encryptMsg := ccc.EncryptMsg

	// 1. Base64解码AESKey
	aesKey, err := base64.StdEncoding.DecodeString(encodingAESKey)
	if err != nil {
		fmt.Println("Decode AESKey error:", err)
		return
	}

	// 2. Base64解码加密消息
	cipherText, err := base64.StdEncoding.DecodeString(encryptMsg)
	if err != nil {
		fmt.Println("Decode encrypt message error:", err)
		return
	}

	// 3. AES解密
	block, err := aes.NewCipher(aesKey)
	if err != nil {
		fmt.Println("New cipher block error:", err)
		return
	}

	iv := aesKey[:aes.BlockSize]
	mode := cipher.NewCBCDecrypter(block, iv)
	plainText := make([]byte, len(cipherText))
	mode.CryptBlocks(plainText, cipherText)

	// 4. 去除PKCS#7填充
	plainText = PKCS7UnPadding(plainText)

	// 5. 解析消息结构
	// 格式: random(16B) + msg_len(4B) + msg + appid
	if len(plainText) <= 20 {
		fmt.Println("Invalid plain text length")
		return
	}

	msgLen := binary.BigEndian.Uint32(plainText[16:20])
	if len(plainText) <= 20+int(msgLen) {
		fmt.Println("Invalid message length")
		return
	}

	random := plainText[:16]
	msg := plainText[20 : 20+msgLen]
	decodedAppID := string(plainText[20+msgLen:])

	fmt.Printf("Random: %x\n", random)
	fmt.Printf("MsgLen: %d\n", msgLen)
	fmt.Printf("Message: %s\n", msg)
	fmt.Printf("AppID: %s\n", decodedAppID)

	fmt.Println("Decryption successful!")
}

// PKCS7UnPadding 去除PKCS#7填充
func PKCS7UnPadding(data []byte) []byte {
	length := len(data)
	if length == 0 {
		return data
	}
	unPadding := int(data[length-1])
	return data[:(length - unPadding)]
}

// 校验微信签名
func CheckSignature(signature, timestamp, nonce string) bool {
	// 1. 将token、timestamp、nonce三个参数进行字典序排序
	strs := []string{token, timestamp, nonce}
	sort.Strings(strs)

	// 2. 将三个参数字符串拼接成一个字符串
	str := strings.Join(strs, "")

	// 3. 进行sha1加密
	h := sha1.New()
	h.Write([]byte(str))
	sha1Str := fmt.Sprintf("%x", h.Sum(nil))

	// 4. 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
	return sha1Str == signature
}
